package virtualpostit.com;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import model.Waypoint;
import java.util.TimerTask;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import com.google.android.maps.GeoPoint;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class PushNotificationService extends Service {

	protected double myPrevLat = -1;
	protected double myPrevLong = -1;
	protected double myLat;
	protected double myLong;
	// Attributi di classe
	private static final long POLLING_RATE = 90000;
	private NotificationManager mNM;
	private Timer timer = new Timer(); 
	private static final int WAIT_BEFORE_START = 10000;
	private static final int RADIUS = 1;
	private List<Waypoint> list;
	private int NOTIFICATION = R.string.local_service_started;
	private final IBinder mBinder = new LocalBinder();

	/**
	 *Classe che permette ai client di accedere al servizio. Sapendo che il servizio 
	 *gira sempre nello stesso processo come del resto gli stessi client, non abbiamo 
	 *bisogno di IPC.
	 */
	public class LocalBinder extends Binder {
		PushNotificationService getService() {
			return PushNotificationService.this;
		}
	}

	/*
	 * Metodo che inizializzerà il servizio alla creazione
	 * @see android.app.Service#onCreate()
	 */
	@Override
	public void onCreate() {
		mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
		startServicePush();
		Toast.makeText(this, R.string.local_service_started, Toast.LENGTH_LONG).show();
	}

	// Metodo che fa partire il servizio. Il servizio girerà sempre in background
	// ma ogni quanto di tempo si aggiornerà.
	private void startServicePush() {

		timer.scheduleAtFixedRate( new TimerTask() {

			public void run() {

				myLat=GenericMapActivity.getRound(GenericMapActivity.getLocationManager().getLastKnownLocation("gps").getLatitude(),5);
				myLong=GenericMapActivity.getRound(GenericMapActivity.getLocationManager().getLastKnownLocation("gps").getLongitude(),5);

				if(myPrevLat!=myLat || myPrevLong!=myLong){
					myPrevLat = myLat;
					myPrevLong = myLong;
					Log.i("myPrevLat",String.valueOf(myPrevLat));
					Log.i("myPrevLong",String.valueOf(myPrevLong));
					String response="";
					WebService push = new WebService(LoginActivity.SERVER_HOST + ":"	+ LoginActivity.SERVER_PORT);
					ArrayList<NameValuePair> params = new ArrayList<org.apache.http.NameValuePair>();
					params.add(new BasicNameValuePair("radius", String.valueOf(RADIUS)));
					params.add(new BasicNameValuePair("myLatitude", String.valueOf(myLat)));
					params.add(new BasicNameValuePair("myLongitude", String.valueOf(myLong)));
					response = push.webPost("/searchPush.php", params);
					try {
						Log.i("response", response);
						String r = response.replace("\n", "").trim();
						if (!r.equals("null")) {
							ArrayList<GeoPoint> gpl = new ArrayList<GeoPoint>();
							Type collectionType = new TypeToken<ArrayList<Waypoint>>() {}.getType();
							list = new Gson().fromJson(response,collectionType);
							for (Waypoint l : list) {
								Log.i("waypoint", l.toString());
								Double geoLat = l.getLat() * 1E6;
								Double geoLong = l.getLongit() * 1E6;
								GeoPoint g = new GeoPoint(geoLat.intValue(),geoLong.intValue());
								gpl.add(g);
							}

							if(gpl!= null && gpl.size()>0)
								showNotification();
						} 			


					} catch (Exception e) {
						Log.i("Errore", e.getMessage());
					}
				}
			}

		}, WAIT_BEFORE_START, POLLING_RATE);


	}


	/*
	 * Vogliamo che il servizio resti attivo fino a quanto non sarà stoppato
	 * esplicitamente, pertanto ritorno sticky.(non-Javadoc)
	 * @see android.app.Service#onStartCommand(android.content.Intent, int, int)
	 */
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i("LocalService", "Received start id " + startId + ": " + intent);
		return START_STICKY;
	}

	/*
	 * Metodo che si occuperà della distruzione del servizio.
	 * @see android.app.Service#onDestroy()
	 */
	@Override
	public void onDestroy() {
		// Cancello la notifica persistente
		mNM.cancel(NOTIFICATION);
		// Stoppo il servizio e invio un messaggio a video
		stopservice();
		Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_LONG).show();
	}

	// Azzero il timer appena il servizio verrà stoppato dall'utente.
	private void stopservice() {
		if (timer != null)
			timer.cancel();
	}

	/*
	 * @see android.app.Service#onBind(android.content.Intent)
	 */
	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}

	//Metodo che permette di mostrare a video una notifica mentre il servizio è attivo.
	private void showNotification() {
		CharSequence text = getText(R.string.clickToDisplay);
		Notification notification = new Notification(R.drawable.ballon, "Nuova Notifica",	System.currentTimeMillis());
		Intent in= new Intent(this,GenericMapActivity.class);
		in.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,in, 0);
		notification.setLatestEventInfo(this, "Virtual Post-it",text, contentIntent);
		notification.flags = Notification.FLAG_AUTO_CANCEL;
		mNM.notify(NOTIFICATION, notification);
	}

}
